﻿#pragma once
#ifndef ASTART_H
#define ASTART_H
#include <vector>
#include <functional>

/*
 *@公司 潭州教育
 *@班期c++ 35期的项目
 *@作者 小雨滴
 *@版本 1.0
 */
namespace CPP35{
	using std::vector;
	using std::function;
	//路径的节点
	struct Node
	{
		int x;							//坐标
		int y;
		int G;							//从起点到当前位置的值
		int H;							//从当前位置到终点预估的值
		int getF(){ return G + H; }		//和值  F=(G+H)
		Node *parent;					//指向前面的节点,找到终点可以退回到起点
		Node(int x, int y, int G, int H, Node *p = nullptr)
			:x(x), y(y), G(G), H(H), parent(p){}
	};

	//坐标类
	struct Vec2
	{
		int x;
		int y;
		Vec2(int x = 0, int y = 0) :x(x), y(y){}
	};

	//A星寻路
	class Astart
	{
	private:
		vector<Node*> openList;			//准备要走的路径
		vector<Node*> closeList;		//正在走的路径或已经走过的路径

		Vec2 end;						//终点

		/*计算当前位置到终点位置预估的值
		 *@now 当前的位置
		 *@return 计算出H的值
		 */
		int getH(Vec2 now);

		/*
		* 开始寻找附近的路径,将周围的路径加入open列表
		* @n 当前路径的位置
		*/
		void addRound(Node *n);

		/*
		*过滤无效的位置
		*@v2 准备判断的坐标
		*return 是否有效
		*/
		bool filer(Vec2 v2);

		/*判断是否走过该路径
		*@ls 列表
		*@v2 当前的坐标是否是已经走过了
		*@return 是否已经走过了
		*/
		bool isVisited(vector<Node*> &ls, Vec2 v2);

		//销毁所有节点
		void destory();

	public:

		Astart(function<bool(Vec2 v2)> outFiler) :outFiler(outFiler){}
		/*
		 *A星寻路函数算法
		 * @start		起点的坐标
		 * @end			终点的坐标
		 * @path[out]	寻找到的最短路径
		 * @return		成功找到终点位置,返回一个true,反之返回false
		 */
		bool findPath(Vec2 start, Vec2 end, vector<Vec2>& path);

	

		function<bool(Vec2 v2)> outFiler;  //声明一个外部函数接口
	};
}

#endif //ASTART_H
